package com.zs.propertymanage.controller;

import com.zs.propertymanage.annotation.SystemLog;
import com.zs.propertymanage.dataObj.R;
import com.zs.propertymanage.dataObj.entity.Employee;
import com.zs.propertymanage.dataObj.entity.Manager;
import com.zs.propertymanage.dataObj.entity.Tenant;
import com.zs.propertymanage.mapper.LoginMapper;
import com.zs.propertymanage.service.impl.EmployeeService;
import com.zs.propertymanage.service.impl.ManagerService;
import com.zs.propertymanage.service.impl.TenantService;
import com.zs.propertymanage.utils.JwtUtil;
import com.zs.propertymanage.utils.MD5Util;
import com.zs.propertymanage.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
@CrossOrigin
public class LoginController {

    @Autowired
    private LoginMapper loginMapper;
    @Autowired
    private ManagerService managerService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private TenantService tenantService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @PostMapping("/login")
    @SystemLog(name = "登录")
    public R login(@RequestBody Map<String, String> loginParams) {
        String account = loginParams.get("account");
        String password = loginParams.get("password");
        String identity = loginParams.get("identity");
        Map<String, String> userInfo = new HashMap<>();
        switch (identity) {
            case "1":
                Manager manager = loginMapper.managerLogin(account, password);
                if (manager == null) {
                    return R.error("管理员登录失败，账号或密码错误");
                }
                if (manager.getStatus() == 0) {
                    return R.error("管理员登录失败，账号已被禁用");
                } else {
                    manager.setPassword(null);
                    userInfo.put("manager", manager.toString());
                    userInfo.put("id", manager.getId());
                    userInfo.put("name", manager.getName());
                    userInfo.put("identity", "管理员");
                    String token = JwtUtil.generateToke(userInfo);
                    manager.setToken(token);
                    // 保存token到redis 并设置过期时间为3小时
                    stringRedisTemplate.opsForValue().set("user jwt token:" + manager.getId(), token, 3, TimeUnit.HOURS);
                    // 保存token到ThreadLocal中
                    ThreadLocalUtil.set(token);
                    return R.ok("管理员登录成功", manager);
                }
            case "2":
                Employee employee = loginMapper.employeeLogin(account, password);
                if (employee == null) {
                    return R.error("员工登录失败，账号或密码错误");
                }
                if (employee.getStatus() == 0) {
                    return R.error("员工登录失败，账号已被禁用");
                } else {
                    employee.setPassword(null);
                    userInfo.put("employee", employee.toString());
                    userInfo.put("id", employee.getId());
                    userInfo.put("name", employee.getName());
                    userInfo.put("identity", "员工");
                    String token = JwtUtil.generateToke(userInfo);
                    employee.setToken(token);
                    stringRedisTemplate.opsForValue().set("user jwt token:" + employee.getId(), token, 3, TimeUnit.HOURS);
                    ThreadLocalUtil.set(token);
                    return R.ok("员工登录成功", employee);
                }
            case "3":
                Tenant tenant = loginMapper.tenantLogin(account, password);
                if (tenant == null) {
                    return R.error("租户登录失败，账号或密码错误");
                }
                if (tenant.getStatus() == 0) {
                    return R.error("租户登录失败，账号已被禁用");
                } else {
                    tenant.setPassword(null);
                    userInfo.put("tenant", tenant.toString());
                    userInfo.put("id", tenant.getId());
                    userInfo.put("name", tenant.getName());
                    userInfo.put("identity", "租户");
                    String token = JwtUtil.generateToke(userInfo);
                    tenant.setToken(token);
                    stringRedisTemplate.opsForValue().set("user jwt token:" + tenant.getId(), token, 3, TimeUnit.HOURS);
                    ThreadLocalUtil.set(token);
                    return R.ok("租户登录成功", tenant);
                }
            default:
                return R.error("未正确选择身份");
        }
    }

    @PostMapping("/register")
    @SystemLog(name = "注册") // 注册失败时，日志中显示操作者为系统
    public R register(@RequestBody Map<String, Object> registerParams) {
        // 必要信息检查
        if (ObjectUtils.isEmpty(registerParams.get("name")) || ObjectUtils.isEmpty(registerParams.get("phone")) || ObjectUtils.isEmpty(registerParams.get("password")) || ObjectUtils.isEmpty(registerParams.get("identity")))
            return R.error("注册信息不完善 (至少填写姓名、电话、密码、身份)");
        // 生成用户ID
        String userId = UUID.randomUUID().toString();
        registerParams.put("id", userId);

        // 生成用于日志的token
        String identity = (String) registerParams.get("identity");
        HashMap<String, String> userInfo = new HashMap<>();
        userInfo.put("id", userId);
        userInfo.put("name", (String) registerParams.get("name"));
        userInfo.put("identity", identity.equals("1") ? "管理员" : (identity.equals("2") ? "员工" : "租户"));
        String token = JwtUtil.generateToke(userInfo);

        // 根据身份初始化注册对象并注册
        switch ((String) registerParams.get("identity")) {
            case "1":
                Manager registerManager = new Manager();
                registerManager.setId((String) registerParams.get("id"));
                registerManager.setName((String) registerParams.get("name"));
                registerManager.setPhone((String) registerParams.get("phone"));
                registerManager.setPassword((String) registerParams.get("password"));
                registerManager.setEmail((String) registerParams.get("email"));
                registerManager.setAddress((String) registerParams.get("address"));
                registerManager.setGender(Integer.parseInt((String) registerParams.get("gender")));
                registerManager.setIdentity(Integer.parseInt((String) registerParams.get("identity")));
                if (loginMapper.addManager(registerManager) == 1) {
                    ThreadLocalUtil.set(token);
                    return R.ok("管理员注册成功");
                } else
                    return R.error("管理员注册失败");
            case "2":
                Employee registerEmployee = new Employee();
                registerEmployee.setId((String) registerParams.get("id"));
                registerEmployee.setName((String) registerParams.get("name"));
                registerEmployee.setPhone((String) registerParams.get("phone"));
                registerEmployee.setPassword((String) registerParams.get("password"));
                registerEmployee.setEmail((String) registerParams.get("email"));
                registerEmployee.setAddress((String) registerParams.get("address"));
                registerEmployee.setGender(Integer.parseInt((String) registerParams.get("gender")));
                registerEmployee.setIdentity(Integer.parseInt((String) registerParams.get("identity")));
                System.err.println(registerEmployee);
                if (loginMapper.addEmployee(registerEmployee) == 1) {
                    ThreadLocalUtil.set(token);
                    return R.ok("员工注册成功");
                } else
                    return R.error("员工注册失败");
            case "3":
                Tenant registerTenant = new Tenant();
                registerTenant.setId((String) registerParams.get("id"));
                registerTenant.setName((String) registerParams.get("name"));
                registerTenant.setPhone((String) registerParams.get("phone"));
                registerTenant.setPassword((String) registerParams.get("password"));
                registerTenant.setEmail((String) registerParams.get("email"));
                registerTenant.setAddress((String) registerParams.get("address"));
                registerTenant.setGender(Integer.parseInt((String) registerParams.get("gender")));
                registerTenant.setIdentity(Integer.parseInt((String) registerParams.get("identity")));
                if (loginMapper.addTenant(registerTenant) == 1) {
                    ThreadLocalUtil.set(token);
                    return R.ok("租户注册成功");
                } else
                    return R.error("租户注册失败");
            default:
                return R.error("未正确选择身份");
        }
    }

    @GetMapping("/logout/{userId}")
    @SystemLog(name = "退出")
    public R logout(@PathVariable String userId) {
        stringRedisTemplate.delete("user jwt token:" + userId);
        return R.ok("退出成功");
    }

    @PutMapping("/updatePwd")
    @SystemLog(name = "用户修改密码")
    public R updatePwd(@RequestBody Map<String, String> updateParams) {
        String id = updateParams.get("id");
        String phone = updateParams.get("phone");
        String identity = updateParams.get("identity");
        String oldPwd = MD5Util.MD5Encrypt(updateParams.get("oldPwd"));
        String newPwd = MD5Util.MD5Encrypt(updateParams.get("newPwd"));

        switch (identity) {
            case "1":
                Manager manager = loginMapper.managerLogin(phone, oldPwd);
                if (manager == null)
                    return R.error("修改失败，原密码错误！");
                manager.setPassword(newPwd);
                R rm = managerService.updateManager(manager);
                if (rm.getCode() == 200) {
                    stringRedisTemplate.delete("user jwt token:" + id); // 清除token
                    return R.ok("修改成功");
                }
                return R.error("修改失败");
            case "2":
                Employee employee = loginMapper.employeeLogin(phone, oldPwd);
                if (employee == null)
                    return R.error("修改失败，原密码错误！");
                employee.setPassword(newPwd);
                R re = employeeService.updateEmployee(employee);
                if (re.getCode() == 200) {
                    stringRedisTemplate.delete("user jwt token:" + id); // 清除token
                    return R.ok("修改成功");
                }
                return R.error("修改失败");
            case "3":
                Tenant tenant = loginMapper.tenantLogin(phone, oldPwd);
                if (tenant == null)
                    return R.error("修改失败，原密码错误！");
                tenant.setPassword(newPwd);
                R rt = tenantService.updateTenant(tenant);
                if (rt.getCode() == 200) {
                    stringRedisTemplate.delete("user jwt token:" + id); // 清除token
                    return R.ok("修改成功");
                }
                return R.error("修改失败");
            default:
                return R.error("未正确选择身份");
        }

    }

}
